/**
 * @file bodyinfo.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_watch.h"

#if USE_LV_WATCH_BODYINFO!= 0

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void setting_btn_event_cb(lv_obj_t * obj, lv_event_t e);;
static void ok_btn_event_cb(lv_obj_t * obj, lv_event_t e);
static void cancel_btn_event_cb(lv_obj_t * obj, lv_event_t e);
static lv_obj_t * setting_opt_create(lv_obj_t * par);
static lv_obj_t * roller_create(lv_obj_t * par, uint8_t type, uint16_t sel_value);
static void bodyinfo_set(nv_watch_pedometer_setting_t * pedo_set);
static lv_obj_t  * bodyinfo_setting_create(lv_obj_t * activity_obj);
static void bodyinfo_prepare_destory(lv_obj_t * activity_obj);
static void get_optstr_from_num(uint16_t num, char * stropt, uint8_t type);
static void roller_event_cb(lv_obj_t * roller, lv_event_t e);
static uint16_t get_value_from_btn(lv_obj_t * obj);

/**********************
 *  STATIC VARIABLES
 **********************/

/**********************
 *      MACROS
 **********************/
#define  BODYINFO_LAYOUT_PADDING_HOR  10
#define  TEXT_CM    (void*)lv_lang_get_text(WATCH_TEXT_ID_CM)
#define  TEXT_KG    (void*)lv_lang_get_text(WATCH_TEXT_ID_KG)
#define  TEXT_STEP  (void*)lv_lang_get_text(WATCH_TEXT_ID_STEPS)
/**********************
 *   GLOBAL FUNCTIONS
***********************/

lv_obj_t * bodyinfo_create(lv_obj_t * tileview, uint16_t id)
{
    char str[16];
    lv_obj_t * tab = launcher_tileview_add_tile(tileview, id);
    LV_ASSERT_MEM(tab);
    if(tab == NULL) return NULL;

    nv_watch_pedometer_setting_t pedo;
    memset(&pedo, 0, sizeof(nv_watch_pedometer_setting_t));
    bodyinfo_init(&pedo);

    lv_obj_t * content = lv_cont_create(tab, NULL);
    lv_obj_add_style(content, LV_CONT_PART_MAIN, &lv_watch_style_transp);
    lv_obj_set_size(content, lv_obj_get_width(tab) - BODYINFO_LAYOUT_PADDING_HOR * 2, lv_obj_get_height(tab) * 5 / 6);
    lv_obj_align(content, NULL, LV_ALIGN_CENTER, 0, 0);
    lv_cont_set_layout(content, LV_LAYOUT_COLUMN_MID);

    lv_obj_t * title = lv_label_create(content, NULL);
    lv_label_set_text_id(title, WATCH_TEXT_ID_PEDO_SETTING);
    lv_obj_add_style(title, LV_LABEL_PART_MAIN, &lv_watch_font20_gray);

    /*Height*/
    lv_obj_t * btn_height = lv_btn_create(content, NULL);
    lv_btn_set_layout(btn_height, LV_LAYOUT_ROW_MID);
    lv_obj_set_size(btn_height, lv_obj_get_width(content) - BODYINFO_LAYOUT_PADDING_HOR * 2, LV_VER_RES / 5);

    lv_obj_t * img_height = lv_img_create(btn_height, NULL);
    lv_img_set_src(img_height, ICON_BODYHEIGHT);
    lv_obj_set_click(img_height, false);

    lv_obj_t * label_height = lv_label_create(btn_height, NULL);
    lv_label_set_text_id(label_height, WATCH_TEXT_ID_BODY_HEIGHT);
    lv_obj_add_style(label_height, LV_LABEL_PART_MAIN, &lv_watch_font20_gray);
    lv_obj_set_click(label_height, false);

    lv_obj_t * label_height_v = lv_label_create(btn_height, NULL);
    memset(str, 0, 16);
    snprintf(str, 16, "%d", pedo.height);
    strcat(str, " ");
    strcat(str, TEXT_CM);
    lv_label_set_text(label_height_v, str);
    lv_watch_set_free_ptr(label_height, TEXT_CM);
    lv_obj_add_style(label_height_v, LV_LABEL_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label_height_v, LV_LABEL_ALIGN_LEFT);

    lv_label_set_align(label_height_v, LV_LABEL_ALIGN_LEFT);
    lv_obj_set_event_cb(btn_height, setting_btn_event_cb);
    lv_obj_add_style(btn_height, LV_BTN_PART_MAIN, &lv_style_transp_fit);
    lv_watch_set_free_num(btn_height, 0);
    lv_tileview_add_element(tileview, btn_height);

    /*Weight*/
    lv_obj_t * btn_weight = lv_btn_create(content, btn_height);
    lv_obj_t * img_weight = lv_img_create(btn_weight, NULL);
    lv_img_set_src(img_weight, ICON_BODYWEIGHT);

    lv_obj_t * label_weight = lv_label_create(btn_weight, NULL);
    lv_label_set_text_id(label_weight, WATCH_TEXT_ID_BODY_WEIGHT);
    lv_obj_add_style(label_weight, LV_LABEL_PART_MAIN, &lv_watch_font20_gray);

    lv_obj_t * label_weight_v = lv_label_create(btn_weight, label_height_v);
    memset(str, 0, 16);
    snprintf(str, 16, "%d", pedo.weight);
    strcat(str, " ");
    strcat(str, TEXT_KG);
    lv_label_set_text(label_weight_v, str);;
    lv_watch_set_free_ptr(label_weight, TEXT_KG);
    lv_obj_set_event_cb(btn_weight, setting_btn_event_cb);
    lv_watch_set_free_num(btn_weight, 1);
    lv_tileview_add_element(tileview, btn_weight);

    /*Goal*/
    lv_obj_t * btn_goal = lv_btn_create(content, btn_height);
    lv_obj_t * img_goal = lv_img_create(btn_goal, NULL);
    lv_img_set_src(img_goal, ICON_GOAL);

    lv_obj_t * label_goal = lv_label_create(btn_goal, NULL);
    lv_label_set_text_id(label_goal, WATCH_TEXT_ID_GOAL);
    lv_watch_set_free_ptr(label_goal, TEXT_STEP);
    lv_obj_add_style(label_goal, LV_LABEL_PART_MAIN, &lv_watch_font20_gray);

    lv_obj_t * label_goal_v = lv_label_create(btn_goal, label_height_v);
    memset(str, 0, 16);
    snprintf(str, 16, "%d", pedo.goal);
    strcat(str, " ");
    strcat(str, TEXT_STEP);
    lv_label_set_text(label_goal_v, str);
    lv_obj_set_event_cb(btn_goal, setting_btn_event_cb);
    lv_watch_set_free_num(btn_goal, 2);
    lv_tileview_add_element(tileview, btn_goal);

    lv_tileview_add_element(tileview, content);
    return tab;
}

void bodyinfo_init(nv_watch_pedometer_setting_t * pedo_set)
{
    //read from nv
    UI_NV_Read_Req(NV_SECTION_UI_PEDOMETER, NV_PEDOMETER_SETTING_OFFSET, NV_PEDOMETER_SETTING_LEN, (uint8_t *)pedo_set);
}
/**********************
 *   STATIC FUNCTIONS
 **********************/

static void bodyinfo_set(nv_watch_pedometer_setting_t * pedo_set)
{
    //write to nv
    UI_NV_Write_Req(NV_SECTION_UI_PEDOMETER, NV_PEDOMETER_SETTING_OFFSET, NV_PEDOMETER_SETTING_LEN, (uint8_t *)pedo_set);
}

static void bodyinfo_prepare_destory(lv_obj_t * activity_obj)
{
    lv_watch_png_cache_all_free();
}

static lv_bodyinfo_ext_t * bodyinfo_get_ext(void)
{
    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_BODYINFO_ADJUST);
    if(activity_obj == NULL) return NULL;

    lv_obj_t * watch_obj;
    lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &watch_obj);
    if(watch_obj == NULL) return NULL;

    if(watch_obj) {
        lv_bodyinfo_ext_t  * ext = lv_obj_get_ext_attr(watch_obj);
        return ext;
    }
    return NULL;
}

static lv_obj_t  * bodyinfo_setting_create(lv_obj_t * activity_obj)
{
    lv_watch_activity_ext_t activity_ext;
    memset(&activity_ext, 0, sizeof(lv_watch_activity_ext_t));
    activity_ext.actId = ACT_ID_BODYINFO_ADJUST;
    activity_ext.create =  bodyinfo_setting_create;
    activity_ext.prepare_destory = bodyinfo_prepare_destory;
    activity_obj = lv_watch_creat_activity_obj(&activity_ext);
    LV_ASSERT_MEM(activity_obj);

    lv_obj_t * obj = lv_watch_obj_create(activity_obj);
    LV_ASSERT_MEM(obj);

    return obj;
}

static uint16_t get_value_from_btn(lv_obj_t * obj)
{
    char * sel_str = NULL;
    uint16_t sel_value = 0;
    char temp[20] = {0};
    uint8_t i = 0;
    sel_str = lv_label_get_text(lv_obj_get_child(obj, NULL));
    for(i = 0; i < strlen(sel_str); i++) {
        if(sel_str[i] && sel_str[i] >= '0' && sel_str[i] <= '9') {
            temp[i] = sel_str[i];
        }

    }
    temp[i + 1] = '\0';
    sel_value = atoi(temp);

    return sel_value;
}

static void setting_btn_event_cb(lv_obj_t * obj, lv_event_t e)
{
    uint8_t num = 0;
    lv_obj_t * child_obj = NULL;
    uint16_t sel_value = 0;
    if(LV_EVENT_CLICKED == e)
    {
        child_obj = bodyinfo_setting_create(NULL);

        /*Allocate the object type specific extended data*/
        lv_bodyinfo_ext_t * ext = lv_obj_allocate_ext_attr(child_obj, sizeof(lv_bodyinfo_ext_t));
        LV_ASSERT_MEM(ext);
        _lv_memset_00((uint8_t *)ext + sizeof(ext->lv_watch_obj),
                      sizeof(lv_bodyinfo_ext_t) - sizeof(ext->lv_watch_obj));
        ext->label = lv_obj_get_child(obj, NULL);

        num = lv_obj_get_user_data(obj).user_num;

        if(num == 0) {
            ext->height = get_value_from_btn(obj);
            ext->weight = get_value_from_btn(lv_obj_get_child_back(lv_obj_get_parent(obj), obj));
            ext->step  = get_value_from_btn(lv_obj_get_child(lv_obj_get_parent(obj), NULL));
            sel_value = ext->height;
        } else if(num == 1) {
            ext->height = get_value_from_btn(lv_obj_get_child(lv_obj_get_parent(obj), obj));
            ext->weight = get_value_from_btn(obj);
            ext->step  = get_value_from_btn(lv_obj_get_child(lv_obj_get_parent(obj), NULL));
            sel_value = ext->weight;
        } else if(num == 2) {
            ext->height = get_value_from_btn(lv_obj_get_child(lv_obj_get_parent(obj), lv_obj_get_child(lv_obj_get_parent(obj), obj)));
            ext->weight = get_value_from_btn(lv_obj_get_child(lv_obj_get_parent(obj), obj));
            ext->step  = get_value_from_btn(obj);
            sel_value = ext->step;
        }
        // printf("num = %d height = %d w = %d g = %d\n", num,ext->height, ext->weight, ext->step);
        roller_create(child_obj, num, sel_value);
        setting_opt_create(child_obj);
    }
}

static void roller_event_cb(lv_obj_t * roller, lv_event_t e)
{
    if(LV_EVENT_VALUE_CHANGED == e)
    {
        printf("roller_event_cb\n");
        uint16_t sel_val = 0;
        char sel_str[10];
        char stropt[40];

        memset(sel_str, 0, 10);
        memset(stropt, 0, 40);

        lv_roller_get_selected_str(roller, sel_str, 10);

        sel_val = atoi(sel_str);
        get_optstr_from_num(sel_val, stropt, lv_obj_get_user_data(roller).user_num);
        lv_roller_set_options(roller, stropt, LV_ROLLER_MODE_NORMAL);
        lv_roller_set_selected(roller, 2, LV_ANIM_OFF);
        lv_roller_set_auto_fit(roller, true);
    }
}

static lv_obj_t * roller_create(lv_obj_t * par, uint8_t type, uint16_t sel_value)
{
    char roller_opt[40];
    char * text = NULL;
    lv_bodyinfo_ext_t * ext = bodyinfo_get_ext();

    memset(roller_opt, 0, 40);
    if(type == 0) {
        text = TEXT_CM;
    } else if(type == 1) {
        text = TEXT_KG;
    } else if(type == 2) {
        text = (char *)TEXT_STEP;
    }
    get_optstr_from_num(sel_value, roller_opt, type);

    lv_obj_t * cont = lv_cont_create(par, NULL);
    lv_cont_set_fit2(cont, LV_FIT_NONE, LV_FIT_TIGHT);
    lv_obj_set_width(cont, LV_HOR_RES * 3 / 5);
    lv_obj_set_y(cont, 20);
    lv_cont_set_layout(cont, LV_LAYOUT_OFF);
    lv_obj_add_style(cont, LV_CONT_PART_MAIN, &lv_watch_style_transp);

    lv_obj_t * roller = lv_roller_create(cont, NULL);
    ext->info_roller = roller;
    lv_obj_set_style_local_bg_opa(roller, LV_ROLLER_PART_BG, LV_STATE_DEFAULT, LV_OPA_TRANSP);
    lv_obj_set_style_local_text_line_space(roller, LV_ROLLER_PART_BG, LV_STATE_DEFAULT, 20);
    lv_obj_set_style_local_text_color(roller, LV_ROLLER_PART_BG, LV_STATE_DEFAULT, LV_COLOR_GRAY);
    lv_obj_set_style_local_bg_opa(roller, LV_ROLLER_PART_SELECTED, LV_STATE_DEFAULT, LV_OPA_TRANSP);
    lv_obj_set_style_local_text_line_space(roller, LV_ROLLER_PART_SELECTED, LV_STATE_DEFAULT, 20);

    lv_roller_set_options(roller, roller_opt, LV_ROLLER_MODE_NORMAL);
    lv_roller_set_visible_row_count(roller, 3);
    lv_roller_set_selected(roller, 2, LV_ANIM_OFF);
    lv_obj_set_event_cb(roller, roller_event_cb);
    lv_watch_set_free_num(roller, type);

    lv_watch_roller_set_sel_style(roller, ext->sel_str);

    lv_obj_t * label = lv_label_create(par, NULL);
    if(lv_obj_get_base_dir(par) == LV_BIDI_DIR_RTL)
        lv_obj_align(label, cont, LV_ALIGN_OUT_LEFT_MID, 0, 0);
    else
        lv_obj_align(label, cont, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
    lv_label_set_text(label, text);
    lv_obj_add_style(label, LV_LABEL_PART_MAIN, &lv_watch_font20_gray);
    lv_watch_tabview_add_element(roller);
    ext->info_label = label;
    return cont;
}

static lv_obj_t * setting_opt_create(lv_obj_t * par)
{
    lv_obj_t * content = lv_cont_create(par, NULL);
    lv_cont_set_fit2(content, LV_FIT_NONE, LV_FIT_TIGHT);
    lv_obj_set_width(content, LV_HOR_RES);
    lv_cont_set_layout(content, LV_LAYOUT_ROW_MID);
    LV_ASSERT_MEM(content);
    if(content == NULL) return NULL;
    lv_obj_set_click(content, false);
    lv_obj_align(content, par, LV_ALIGN_IN_BOTTOM_MID, 0, -LV_VER_RES / 8);
    lv_obj_set_style_local_bg_opa(content, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP);
    lv_obj_set_style_local_pad_left(content, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 20);
    lv_obj_set_style_local_pad_right(content, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 20);
    lv_obj_set_style_local_pad_inner(content, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 70);

    lv_obj_t * btn;
    btn = lv_imgbtn_create(content, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_CANCEL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_CANCEL);
    lv_obj_set_event_cb(btn, cancel_btn_event_cb);
    lv_watch_obj_add_element(btn);

    btn = lv_imgbtn_create(content, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_OK);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_OK);
    lv_obj_set_event_cb(btn, ok_btn_event_cb);
    lv_watch_obj_add_element(btn);


    return content;
}

static void cancel_btn_event_cb(lv_obj_t * obj, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e)
    {
        lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_BODYINFO_ADJUST);
        lv_obj_del(activity_obj);
    }
}

static void ok_btn_event_cb(lv_obj_t * obj, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e)
    {
        char * label_str = NULL;
        char sel_str[16];
        lv_obj_t * roller = NULL;
        lv_obj_t * label = NULL;
        uint16_t sel_val = 0;
        lv_bodyinfo_ext_t * ext = bodyinfo_get_ext();

        roller = ext->info_roller;
        label = ext->info_label;

        memset(sel_str, 0, 16);
        lv_roller_get_selected_str(roller, sel_str, 16);
        sel_val = atoi(sel_str);
        label_str = lv_label_get_text(label);
        strcat(sel_str, " ");
        strcat(sel_str, label_str);
        if(strcmp(label_str, TEXT_CM) == 0) {
            ext->height = sel_val;
        } else if(strcmp(label_str, TEXT_KG) == 0) {
            ext->weight = sel_val;
        } else  if(strcmp(label_str, TEXT_STEP) == 0) {
            ext->step = sel_val;
            pedometer_update_goal(sel_val);
        }

        lv_label_set_text(ext->label, sel_str);

        nv_watch_pedometer_setting_t pedo_set;
        pedo_set.height = ext->height;
        pedo_set.weight = ext->weight;
        pedo_set.goal = ext->step;
        bodyinfo_set(&pedo_set);

        lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_BODYINFO_ADJUST);
        lv_obj_del(activity_obj);
    }
}

static void get_optstr_from_num(uint16_t num, char * stropt, uint8_t type)
{
    uint16_t opt_display[5];
    uint8_t i, pos = 0;
    uint16_t min = 0;
    uint16_t max = 0;
    uint16_t count = 0;
    uint16_t step = 0;
    if(type == 0) { //height
        min = 30;
        max = 250;
        count = 221;
        step = 1;
    } else if(type == 1) { //weight
        max = 150;
        min = 15;
        count = 136;
        step = 1;
    } else if(type == 2) { //step
        min = 500;
        max = 50000;
        count = (max - min) / 500 + 1;
        step = 500;
    }

    opt_display[0] = ((num - min + count * step) - step * 2) % (count * step) + min;
    opt_display[1] = ((num - min + count * step) - step * 1) % (count * step) + min;
    opt_display[2] = num;
    opt_display[3] = (num + step * 1 - min) % (count * step) + min;
    opt_display[4] = (num + step * 2 - min) % (count * step) + min;


    for(i = 0; i < 5; i++) {
        if(opt_display[i] > 99) {
            if(opt_display[i] > 999) {
                if(opt_display[i] > 9999) {
                    stropt[pos++] =  opt_display[i] / 10000 + 0x30;
                }
                stropt[pos++] = (opt_display[i] % 10000) / 1000 + 0x30;
            }
            stropt[pos++] = (opt_display[i] % 1000) / 100 + 0x30;
        }


        stropt[pos++] = (opt_display[i] % 100) / 10 + 0x30;
        stropt[pos++] = opt_display[i] % 10 + 0x30;
        stropt[pos++] = 0x0A;
    }
    stropt [pos - 1] = 0;

}

#endif /*USE_LV_WATCH_BODYINFO*/
